//
//  UniversalEngine.m
//  易商城
//
//  Created by SongZhiyuan on 14/10/22.
//  Copyright (c) 2014年 Mac4. All rights reserved.
//

#import "UniversalEngine.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

#import <SDWebImage/SDImageCache.h>

#define     LocalStr_None           @""
#define VIewline_tag 0x10101011

static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static NSTimeInterval cacheTime =  (double)604800;


@implementation UniversalEngine


+(instancetype)sharedInstance
{
    static UniversalEngine *sharedInstance=nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedInstance=[[self alloc] init];
    });
    return sharedInstance;
}

-(NSString *)getStringDateFromJSON:(NSString *)dateString
{
    // Expect date in this format "/Date(1268123281843)/"
    NSInteger startPos = [dateString rangeOfString:@"("].location+1;
    NSInteger endPos = [dateString rangeOfString:@")"].location;
    NSRange range = NSMakeRange(startPos,endPos-startPos);
    unsigned long long milliseconds = [[dateString substringWithRange:range] longLongValue];
    NSTimeInterval interval = milliseconds/1000;
    NSDate *dataTime= [NSDate dateWithTimeIntervalSince1970:interval];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    //zzz表示时区，zzz可以删除，这样返回的日期字符将不包含时区信息。
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    return [dateFormatter stringFromDate:dataTime];
}

+ (NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, (CC_LONG)strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}
// 32位MD5加密方式
+ (NSString *) getMd5_32Bit_String:(NSString *)srcString
{
    const char *cStr = [srcString UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, (int)strlen(cStr), digest );
    NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
        [result appendFormat:@"%02x", digest[i]];
    return result;
}


+ (NSString *)base64StringFromText:(NSString *)text
{
    if (text && ![text isEqualToString:LocalStr_None]) {
        NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
        return [self base64EncodedStringFrom:data];
    }
    else {
        return LocalStr_None;
    }
}

+ (NSString *)textFromBase64String:(NSString *)base64
{
    if (base64 && ![base64 isEqualToString:LocalStr_None]) {
        NSData *data = [self dataWithBase64EncodedString:base64];
        return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }
    else {
        return LocalStr_None;
    }
}

/**文本数据进行DES加密*/
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
{
    char keyPtr[kCCKeySizeAES256+1];
    bzero(keyPtr, sizeof(keyPtr));
    
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [data length];
    
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,kCCOptionPKCS7Padding | kCCOptionECBMode,keyPtr, kCCBlockSizeDES,NULL,[data bytes], dataLength,buffer, bufferSize,&numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    
    free(buffer);
    return nil;
}
/***文本数据进行DES解密 此函数不可用于过长文本*/
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
    char keyPtr[kCCKeySizeAES256+1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,kCCOptionPKCS7Padding | kCCOptionECBMode,keyPtr, kCCBlockSizeDES,NULL,[data bytes], dataLength,buffer, bufferSize,&numBytesDecrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    
    free(buffer);
    return nil;
}

/**
 函数描述 : base64格式字符串转换为文本数据
 */
+ (NSData *)dataWithBase64EncodedString:(NSString *)string
{
    if (string == nil)
//        [NSException raise:NSInvalidArgumentException format:nil];
    if ([string length] == 0)
        return [NSData data];
    static char *decodingTable = NULL;
    if (decodingTable == NULL){
        decodingTable = malloc(256);
        if (decodingTable == NULL)
            return nil;
        memset(decodingTable, CHAR_MAX, 256);
        NSUInteger i;
        for (i = 0; i < 64; i++)
            decodingTable[(short)encodingTable[i]] = i;
    }
    
    const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
    if (characters == NULL)     //  Not an ASCII string!
        return nil;
    char *bytes = malloc((([string length] + 3) / 4) * 3);
    if (bytes == NULL)
        return nil;
    NSUInteger length = 0;
    
    NSUInteger i = 0;
    while (YES){
        char buffer[4];
        short bufferLength;
        for (bufferLength = 0; bufferLength < 4; i++){
            if (characters[i] == '\0')
                break;
            if (isspace(characters[i]) || characters[i] == '=')
                continue;
            buffer[bufferLength] = decodingTable[(short)characters[i]];
            if (buffer[bufferLength++] == CHAR_MAX){
                free(bytes);
                return nil;
            }
        }
        
        if (bufferLength == 0)
            break;
        if (bufferLength == 1){
            free(bytes);
            return nil;
        }
        //  Decode the characters in the buffer to bytes.
        bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
        if (bufferLength > 2)
            bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
        if (bufferLength > 3)
            bytes[length++] = (buffer[2] << 6) | buffer[3];
    }
    
    bytes = realloc(bytes, length);
    return [NSData dataWithBytesNoCopy:bytes length:length];
}

/**文本数据转换为base64格式字符串*/
+ (NSString *)base64EncodedStringFrom:(NSData *)data
{
    if ([data length] == 0)
        return @"";
    char *characters = malloc((([data length] + 2) / 3) * 4);
    if (characters == NULL)
        return nil;
    NSUInteger length = 0;
    
    NSUInteger i = 0;
    while (i < [data length]){
        char buffer[3] = {0,0,0};
        short bufferLength = 0;
        while (bufferLength < 3 && i < [data length])
            buffer[bufferLength++] = ((char *)[data bytes])[i++];
        
        //  Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
        characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
        characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
        if (bufferLength > 1)
            characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
        else characters[length++] = '=';
        if (bufferLength > 2)
            characters[length++] = encodingTable[buffer[2] & 0x3F];
        else characters[length++] = '=';
    }
    
    return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
}

//遍历文件夹获得文件夹大小，返回多少M
- (float ) folderSizeAtPath:(NSString*) folderPath
{
    NSFileManager* manager = [NSFileManager defaultManager];
    if (![manager fileExistsAtPath:folderPath])
        return 0;
    NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];
    NSString* fileName;
    long long folderSize = 0;
    while ((fileName = [childFilesEnumerator nextObject]) != nil){
        NSString* fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
        folderSize += [self fileSizeAtPath:fileAbsolutePath];
    
    }
    return folderSize/(1024.0*1024.0);
}
-(long long) fileSizeAtPath:(NSString*) filePath{
    NSFileManager* manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:filePath]){
        return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
    }
    return 0;
}



//删除 NSUserDefaults的所有数据
+ (void)deleteUserDefaults
{
//    方法一
    /*
    NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
     */
//    方法二
    NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
    NSDictionary * dict = [defs dictionaryRepresentation];
    for (id key in dict) {
        [defs removeObjectForKey:key];
    }
    [defs synchronize];
}

+(CGFloat)calculateTheUserDefaultsCache
{
    NSInteger sunHuan = 0;
    NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
    NSDictionary * dict = [defs dictionaryRepresentation];
    for (id key in dict) {
        id  rowData = [defs valueForKey:key];
        NSData *huancundata = [NSKeyedArchiver archivedDataWithRootObject:rowData];
        sunHuan += huancundata.length;
    }
//    计算SDWebimg的大小
    long long ziJie =[[SDImageCache sharedImageCache] getSize];
    float zijieFloat =(float) ziJie;
    float mb = zijieFloat/1024.00/1024.00;
    CGFloat huanSize = sunHuan/1024.0/1024.0 + mb;
    return huanSize;
    
}

//获取设备的内存情况
+ (NSString *)usedSpaceAndfreeSpace
{
    NSString* path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] ;
    NSFileManager* fileManager = [[NSFileManager alloc ]init];
    NSDictionary *fileSysAttributes = [fileManager attributesOfFileSystemForPath:path error:nil];
    NSNumber *freeSpace = [fileSysAttributes objectForKey:NSFileSystemFreeSize];//空闲空间
    NSNumber *totalSpace = [fileSysAttributes objectForKey:NSFileSystemSize];//总空间
    NSString * neiCunStr = [NSString stringWithFormat:@"总空间%0.1fG/可用空间%0.1fG",[totalSpace longLongValue]/1024.0/1024.0/1024.0 ,[freeSpace longLongValue]/1024.0/1024.0/1024.0] ;
    return neiCunStr;
}

/*添加浏览记录
 *  Product ：商品模型类，用用于归档管理；可根据需要自行设计类
 */
//+(void)addHistory:(id)currentProduct
//{
//    Product *currentProducts = currentProduct;
//    
//    NSUserDefaults* user = [NSUserDefaults standardUserDefaults];
//    NSMutableArray *_browseHistoryData;
//    if (![user valueForKey:BROWSER_HISTORY_KEY]){
//        _browseHistoryData =[[NSMutableArray alloc]init];
//    }else{
//        _browseHistoryData=[[NSMutableArray alloc] initWithArray:[user valueForKey:BROWSER_HISTORY_KEY]];
//    }
//    NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:currentProducts];
//    if(_browseHistoryData.count==0){
//        [_browseHistoryData addObject:encodedObject];
//    }
//    else{
//        Product  *tempProduct;
//        for (int i=0; i<_browseHistoryData.count; i++){
//            Product *model=[NSKeyedUnarchiver unarchiveObjectWithData:[_browseHistoryData objectAtIndex:i]];
//            if ([[NSString stringWithFormat:@"%@",currentProducts.objectID] isEqualToString:[NSString stringWithFormat:@"%@",model.objectID] ]){
//                tempProduct=nil;
//                break;
//            }
//            tempProduct = currentProducts;
//        }
//        if(tempProduct){
//            
//            NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:tempProduct];
//            [_browseHistoryData insertObject:encodedObject atIndex:0];
//            
//        }
//    }
//    [user setObject:_browseHistoryData forKey:BROWSER_HISTORY_KEY];
//}

//查询浏览记录
+(NSMutableArray *)recentBrowseData
{
    NSMutableArray*  _browseHistoryData = [[NSMutableArray alloc] init];
    NSUserDefaults* user = [NSUserDefaults standardUserDefaults];
    if (![user valueForKey:@"BROWSER_HISTORY_KEY"]){
        _browseHistoryData =[[NSMutableArray alloc]init];
    }
    else{
        _browseHistoryData=[[NSMutableArray alloc] initWithArray:[user valueForKey:@"BROWSER_HISTORY_KEY"]];
    }
    return _browseHistoryData;
}
+(void)deletebrowsedata
{
    NSUserDefaults* user = [NSUserDefaults standardUserDefaults];
    [user removeObjectForKey:@"BROWSER_HISTORY_KEY"];
}

+(void)addDataHistory:(NSString *)hisString forKey:(NSString *)key
{
    NSUserDefaults* user = [NSUserDefaults standardUserDefaults];
    NSMutableArray * searchHistoryArray=[[NSMutableArray alloc] initWithArray:[user valueForKey:key]];
    if(hisString.length!=0){
        NSString* strSpace =@" ";
        for(int i = 0;i < hisString.length;i ++) {
            NSString *string = [hisString substringWithRange:NSMakeRange(i, 1)];
            if(![string isEqualToString:strSpace])  {
                NSMutableString* str=[NSMutableString string];
                [str appendString:hisString];
                [str deleteCharactersInRange:NSMakeRange(0, i)];
                hisString=str;
                break;
            } if (i == hisString.length - 1) {
                hisString=nil;
                return;
            }
        }
        if(searchHistoryArray.count==0) {
            //            存储历史搜索的内容
            searchHistoryArray = [NSMutableArray array];
            [searchHistoryArray addObject:hisString];
            
            [user setObject:searchHistoryArray forKey:key];
        }else {
            for (int i=0; i<searchHistoryArray.count; i++) {
                if ([hisString isEqualToString:[searchHistoryArray objectAtIndex:i]]) {
                    [searchHistoryArray removeObjectAtIndex:i];
                    [searchHistoryArray insertObject:hisString atIndex:0];
                    NSUserDefaults* user = [NSUserDefaults standardUserDefaults];
                    [user setObject:searchHistoryArray forKey:key];
                    break;
                }else if (i == searchHistoryArray.count - 1){
                    [searchHistoryArray insertObject:hisString atIndex:0];
                    NSUserDefaults* user = [NSUserDefaults standardUserDefaults];
                    [user setObject:searchHistoryArray forKey:key];
                    break;
                }
            }
        }
    }
}


+(NSMutableArray *)recentSearchDataForKey:(NSString *)key
{
    NSUserDefaults* user = [NSUserDefaults standardUserDefaults];
    NSMutableArray * searchHistoryArray=[[NSMutableArray alloc] initWithArray:[user valueForKey:key]];
    return searchHistoryArray;
}
+(void)deleteSearchDataForKey:(NSString *)key
{
    NSUserDefaults* user = [NSUserDefaults standardUserDefaults];
    [user removeObjectForKey:key];
}


+ (void) resetCache
{
    [[NSFileManager defaultManager] removeItemAtPath:self.cacheDirectory error:nil];
}

+ (NSString*) cacheDirectory
{
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cacheDirectory = [paths objectAtIndex:0];
    cacheDirectory = [cacheDirectory stringByAppendingPathComponent:@"ZYCaches"];
    return cacheDirectory;
}

+ (NSData*) objectForKey:(NSString*)key {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *filename = [self.cacheDirectory stringByAppendingPathComponent:key];
    
    if ([fileManager fileExistsAtPath:filename])
    {
        NSDate *modificationDate = [[fileManager attributesOfItemAtPath:filename error:nil] objectForKey:NSFileModificationDate];
        if ([modificationDate timeIntervalSinceNow] > cacheTime) {
            [fileManager removeItemAtPath:filename error:nil];
        } else {
            NSData *data = [NSData dataWithContentsOfFile:filename];
            return data;
        }
    }
    return nil;
}
+ (void) setObject:(NSData*)data forKey:(NSString*)key {
    
//     [UIImageJPEGRepresentation(data, 1.0f) writeToFile:imageFilePath atomically:YES];//写入图片类型文件
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *filename = [self.cacheDirectory stringByAppendingPathComponent:key];
    
    BOOL isDir = YES;
    if (![fileManager fileExistsAtPath:self.cacheDirectory isDirectory:&isDir]) {
        [fileManager createDirectoryAtPath:self.cacheDirectory withIntermediateDirectories:NO attributes:nil error:nil];
    }
    
    NSError *error;
    @try {
        [data writeToFile:filename options:NSDataWritingAtomic error:&error];
    }
    @catch (NSException * e) {
        //TODO: error handling maybe
    }
}

+ (UIImage *)thumbnailWithImageWithoutScale:(UIImage *)image size:(CGSize)asize
{
    UIImage *newimage;
    if (nil == image) {
        newimage = nil;
    }
    else{
        CGSize oldsize = image.size;
        CGRect rect;
        if (asize.width/asize.height > oldsize.width/oldsize.height) {
            rect.size.width = asize.height*oldsize.width/oldsize.height;
            rect.size.height = asize.height;
            rect.origin.x = (asize.width - rect.size.width)/2;
            rect.origin.y = 0;
        }
        else{
            rect.size.width = asize.width;
            rect.size.height = asize.width*oldsize.height/oldsize.width;
            rect.origin.x = 0;
            rect.origin.y = (asize.height - rect.size.height)/2;
        }
        UIGraphicsBeginImageContext(asize);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
        UIRectFill(CGRectMake(0, 0, asize.width, asize.height));//clear background
        [image drawInRect:rect];
        newimage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    return newimage;
}

/**修发图片大小*/
+ (UIImage *) imageWithImageSimple:(UIImage*)image scaledToSize:(CGSize) newSize
{
    newSize.height=image.size.height*(newSize.width/image.size.width);
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return  newImage;
    
}


/**生成GUID */
+ (NSString *)generateUuidString
{
    CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
    NSString *uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid));
    CFRelease(uuid);
    return uuidString;
}


-(BOOL)validationPhoneFormat:(NSString *)textNum
{
    NSString *mobileRegex = @"^((13[0-9])|(147)|(170)|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
    NSPredicate *mobileTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",mobileRegex];
    BOOL iePhone=   [mobileTest evaluateWithObject:textNum];
    return iePhone;
}

-(NSString *)getNewData
{
    NSDate *  senddate=[NSDate date];
    NSDateFormatter  *dateformatter=[[NSDateFormatter alloc] init];
    [dateformatter setDateFormat:@"YYYY-MM-dd"];
    NSString *  locationString=[dateformatter stringFromDate:senddate];
    return locationString;
}


- (NSMutableArray *)arrayBetweenDate:(NSDate *)date1 anotherDay:(NSDate *)date2
{
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    unsigned int unitFlagsa = NSCalendarUnitDay;
    NSDateComponents *comps = [gregorian components:unitFlagsa fromDate:date1  toDate:date2  options:0];
    NSInteger days = [comps day];
    
    NSMutableArray *dateArray = [NSMutableArray array];
    
    NSDate *startDate = days < 0 ? date2 : date1;
    
    for (NSInteger i = 0; i < days; i++) {
        
        NSTimeInterval aTimeInterval = [startDate timeIntervalSinceReferenceDate] + 86400 * i;
        NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
        
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy-MM-dd"];
        NSString *destDateString = [dateFormatter stringFromDate:newDate];
        NSString *resultString=[NSString stringWithFormat:@"%@",destDateString];
        
        [dateArray addObject:resultString];
        
    }
    return dateArray;
    
}

-(NSDate *)getPriousorLaterDateFromDate:(NSDate *)date withMonth:(int)month
{
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    [comps setMonth:month];
    NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDate *mDate = [calender dateByAddingComponents:comps toDate:date options:0];
    
//    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
//    NSString *destDateString = [dateFormatter stringFromDate:mDate];
//    NSString *resultString=[NSString stringWithFormat:@"%@",destDateString];
    
    return mDate;
}

- (NSString *)formateDate:(NSString *)dateString withFormate:(NSString *) formate
{
    @try {
        //实例化一个NSDateFormatter对象
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:formate];
        NSDate * nowDate = [NSDate date];
        /////  将需要转换的时间转换成 NSDate 对象
        NSDate * needFormatDate = [dateFormatter dateFromString:dateString];
        /////  取当前时间和转换时间两个日期对象的时间间隔
        /////  这里的NSTimeInterval 并不是对象，是基本型，其实是double类型，是由c定义的:  typedef double NSTimeInterval;
        NSTimeInterval time = [nowDate timeIntervalSinceDate:needFormatDate];
        //// 把间隔的秒数折算成天数和小时数：
        NSString *dateStr = @"";
        if (time<=60) {  //// 1分钟以内的
            dateStr = @"刚刚";
        }else if(time<=60*60){  ////  一个小时以内的
            int mins = time/60;
            dateStr = [NSString stringWithFormat:@"%d分钟前",mins];
        }else if(time<=60*60*24){   //// 在两天内的
            
            [dateFormatter setDateFormat:@"YYYY/MM/dd"];
            NSString * need_yMd = [dateFormatter stringFromDate:needFormatDate];
            NSString *now_yMd = [dateFormatter stringFromDate:nowDate];
            
            [dateFormatter setDateFormat:@"HH:mm"];
            if ([need_yMd isEqualToString:now_yMd]) {
                //// 在同一天
                dateStr = [NSString stringWithFormat:@"今天 %@",[dateFormatter stringFromDate:needFormatDate]];
            }else{
                ////  昨天
                dateStr = [NSString stringWithFormat:@"昨天 %@",[dateFormatter stringFromDate:needFormatDate]];
            }
        }else {
            [dateFormatter setDateFormat:@"yyyy"];
            NSString * yearStr = [dateFormatter stringFromDate:needFormatDate];
            NSString *nowYear = [dateFormatter stringFromDate:nowDate];
            if ([yearStr isEqualToString:nowYear]) {
                ////  在同一年
                [dateFormatter setDateFormat:@"MM月dd日"];
                dateStr = [dateFormatter stringFromDate:needFormatDate];
            }else{
                [dateFormatter setDateFormat:@"yyyy/MM/dd"];
                dateStr = [dateFormatter stringFromDate:needFormatDate];
            }
        }
        
        return dateStr;
    }
    @catch (NSException *exception) {
        return @"";
    }
}
-(NSString *)compareDate:(NSDate *)date
{
    NSTimeInterval secondsPerDay = 24 * 60 * 60;
    NSDate *today = [[NSDate alloc] init];
    NSDate *tomorrow, *yesterday;
    tomorrow = [today dateByAddingTimeInterval: secondsPerDay];
    yesterday = [today dateByAddingTimeInterval: -secondsPerDay];
    
    // 10 first characters of description is the calendar date:
    NSString * todayString = [[today description] substringToIndex:10];
    NSString * yesterdayString = [[yesterday description] substringToIndex:10];
    NSString * tomorrowString = [[tomorrow description] substringToIndex:10];
    
    NSString * dateString = [[date description] substringToIndex:10];
    
    if ([dateString isEqualToString:todayString]){
        return @"今天";
    } else if ([dateString isEqualToString:yesterdayString]){
        return @"昨天";
    }else if ([dateString isEqualToString:tomorrowString]){
        return @"明天";
    }else{
        return dateString;
    }
}

-(BOOL)isNewDayFirstOpen
{
    NSUserDefaults *defaultsa = [NSUserDefaults standardUserDefaults];
    NSString *oldDay =   [defaultsa objectForKey:@"sj"];
    NSDate *  senddate=[NSDate date];
    NSDateFormatter  *dateformatter=[[NSDateFormatter alloc] init];
    [dateformatter setDateFormat:@"dd"];
    NSString *  newDay=[dateformatter stringFromDate:senddate];
    [defaultsa setValue:newDay forKey:@"sj"];
    
    if (!oldDay) {
        return YES;
    }else{
        if ([oldDay isEqualToString:newDay]) {
            return NO;
        }else{
            return YES;
        }
     }
    return NO;
}
/**
 *  生成二维码
 */
+ (UIImage *)imageQRcodeString:(NSString *)string Size:(CGFloat)size withRed:(CGFloat)red Green:(CGFloat)green Blue:(CGFloat)blue
{
    UIImage *qrcode = [self createNonInterpolatedUIImageFormCIImage:[self createQRForString:string] withSize:size];
    UIImage *customQrcode = [self imageBlackToTransparent:qrcode withRed:red andGreen:green andBlue:blue];
    return customQrcode;
}
+ (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size
{
    CGRect extent = CGRectIntegral(image.extent);
    CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
    // create a bitmap image that we'll draw into a bitmap context at the desired size;
    size_t width = CGRectGetWidth(extent) * scale;
    size_t height = CGRectGetHeight(extent) * scale;
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
    CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
    CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
    CGContextScaleCTM(bitmapRef, scale, scale);
    CGContextDrawImage(bitmapRef, extent, bitmapImage);
    // Create an image with the contents of our bitmap
    CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
    // Cleanup
    CGContextRelease(bitmapRef);
    CGImageRelease(bitmapImage);
    return [UIImage imageWithCGImage:scaledImage];
}
+ (CIImage *)createQRForString:(NSString *)qrString {
    // Need to convert the string to a UTF-8 encoded NSData object
    NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
    // Create the filter
    CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    // Set the message content and error-correction level
    [qrFilter setValue:stringData forKey:@"inputMessage"];
    [qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];
    // Send the image back
    return qrFilter.outputImage;
}

#pragma mark - imageToTransparent
void ProviderReleaseData (void *info, const void *data, size_t size){
    free((void*)data);
}
+ (UIImage*)imageBlackToTransparent:(UIImage*)image withRed:(CGFloat)red andGreen:(CGFloat)green andBlue:(CGFloat)blue{
    const int imageWidth = image.size.width;
    const int imageHeight = image.size.height;
    size_t      bytesPerRow = imageWidth * 4;
    uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
    // create context
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,
                                                 kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
    // traverse pixe
    int pixelNum = imageWidth * imageHeight;
    uint32_t* pCurPtr = rgbImageBuf;
    for (int i = 0; i < pixelNum; i++, pCurPtr++){
        if ((*pCurPtr & 0xFFFFFF00) < 0x99999900){
            // change color
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[3] = red; //0~255
            ptr[2] = green;
            ptr[1] = blue;
        }else{
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[0] = 0;
        }
    }
    // context to image
    CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace,
                                        kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,
                                        NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease(dataProvider);
    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
    // release
    CGImageRelease(imageRef);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    return resultUIImage;
}



+ (void)topLine:(UIView*)v andHeight:(CGFloat)h andColor:(UIColor*)c
{
    [[v viewWithTag:VIewline_tag] removeFromSuperview];
    UIView* line = [[UIView alloc] initWithFrame:CGRectMake(0, 0 - (1.0/[UIScreen mainScreen].scale)/2, v.frame.size.width, h <= .5?1.0/[UIScreen mainScreen].scale:h)];
    [line setBackgroundColor:c];
    [v addSubview:line];
}
+ (void)bottomLine:(UIView*)v andHeight:(CGFloat)h andColor:(UIColor*)c
{
    [[v viewWithTag:VIewline_tag] removeFromSuperview];
    UIView* line = [[UIView alloc] initWithFrame:CGRectMake(0, v.frame.size.height - h - (h <= .5?1.0/[UIScreen mainScreen].scale:h - (1.0/[UIScreen mainScreen].scale)/2), v.frame.size.width, h <= .5?1.0/[UIScreen mainScreen].scale:h)];
    [line setTag:VIewline_tag];
    [line setBackgroundColor:c];
    [v addSubview:line];
}
+ (void)bottomLine:(UIView*)v andRect:(CGRect)rc andColor:(UIColor*)c
{
    CGFloat h = rc.size.height;
    [[v viewWithTag:VIewline_tag] removeFromSuperview];
    UIView* line = [[UIView alloc] initWithFrame:CGRectMake(rc.origin.x, v.frame.size.height - h - (h <= .5?1.0/[UIScreen mainScreen].scale:h - (1.0/[UIScreen mainScreen].scale)/2), rc.size.width, h <= .5?1.0/[UIScreen mainScreen].scale:h)];
    [line setTag:VIewline_tag];
    [line setBackgroundColor:c];
    [v addSubview:line];
}

+ (void)sortWithFirstLeter:(NSArray*)aSrcArray andKeyPath:(NSString*)keyPath withCompletionBlock:(void(^)(NSDictionary* sortedDictionary, NSArray* sortedKeys))completion
{
    //初始化数据结构
    NSMutableDictionary* dataList = [[NSMutableDictionary alloc] initWithCapacity:5] ;
    NSArray* array = @[@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z", @"#"];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        for (NSString* key in array){
            NSMutableArray* arr = [[NSMutableArray alloc] initWithCapacity:5] ;
            [dataList setValue:arr forKey:key];
        }
        //        [aSrcArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
//#pa 这儿会发生crash，而且不要这样写
        for (id obj in aSrcArray){
            NSMutableString* str = nil;
            if (!keyPath){
                str = [[NSMutableString alloc] initWithString:obj] ;
            }else{
                NSString* tmp = [obj valueForKeyPath:keyPath];
                NSLog(@"name = %@", tmp);
                if (!tmp){
                    tmp = @"";
                }
                str = [[NSMutableString alloc] initWithString:tmp];
            }
            if (str.length > 0){
                NSString* key = [[str substringToIndex:1] uppercaseString];//取首字母做key
                NSInteger firstLetter = [str characterAtIndex:0]; //取第一个字符的 ASCII 码
                if ((firstLetter >= 'a' && firstLetter <= 'z') || (firstLetter >= 'A' && firstLetter <= 'Z')){
                    [dataList[key] addObject:obj];
                }else if (firstLetter > 0x4e00 && firstLetter < 0x9fff){
                    CFStringTransform((__bridge CFMutableStringRef)str, NULL, kCFStringTransformMandarinLatin, NO);
                    CFStringTransform((__bridge CFMutableStringRef)str, NULL, kCFStringTransformStripDiacritics, NO);
                    key = [[str substringToIndex:1] uppercaseString];
                    [dataList[key] addObject:obj];
                }else{
                    [dataList[@"#"] addObject:obj];
                }
            }
        }
        
        [dataList enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
            if (((NSArray*)dataList[key]).count == 0){
                [dataList removeObjectForKey:key];
            }
        }];
        NSArray* sortedkey = [[NSArray alloc] initWithArray:[dataList.allKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
            NSComparisonResult result = [obj1 compare:obj2];
            return result == NSOrderedDescending;
        }]];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (dataList){
                completion(dataList, sortedkey);
            }
        });
    });
}


+ (void)sortWithFirstLeter:(NSArray*)aSrcArray completionBlock:(void(^)(NSDictionary* sortedDictionary, NSArray* sortedKeys))completion
{
    [UniversalEngine  sortWithFirstLeter:aSrcArray andKeyPath:nil withCompletionBlock:completion];
}

+(NSString*)encryptAESData:(NSString*)string app_key:(NSString*)key
{
    //将nsstring转化为nsdata
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    //使用密码对nsdata进行加密
    NSData *encryptedData = [data AES128EncryptWithKey:key];
    return [encryptedData base64EncodedString];
}
#pragma mark - AES解密
//将带密码的data转成string
+(NSString*)decryptAESData:(NSData*)data  app_key:(NSString*)key
{
    //使用密码对data进行解密
    NSData *decryData = [data AES128DecryptWithKey:key];
    //将解了密码的nsdata转化为nsstring
    NSString *str = [[NSString alloc] initWithData:decryData encoding:NSUTF8StringEncoding];
    NSLog(@"解密后的字符串 :%@",str);
    return str ;
}


@end
